#!/bin/sh

#/** @file        myDiffEnv.sh
#*  @brief        Creat diff env with file list, helpful for push/pull
#*  @author       Schips
#*  @version      v1.1 2023-05-12 Standardization API
#                 v1.0 2020-11-26 Init version
#*  @copyright    Copyright By Schips, All Rights Reserved
#*/


_diff_env_list_todo=".list.todo"
_diff_env_list_done=".list.done"
_diff_env_list_skip=".list.skip"
_diff_env_list_full=".list.full"

_create_help=$(cat << EOF
create dir-1 dri2 file-list  output-path
 - Dir 1       : TOP Path 1 for diff
 - Dir 2       : TOP Path 2 for diff
 - File List   : A list saved some Relative path between DIR1 and DIR2
 - Output Path : Created Env Dir
EOF
)

_done_skip_help=$(cat << EOF
done/skip :  Remove this sub-dir in todo-list.

Must in the dir where has .path_info
EOF
)

_step_help=$(cat << EOF
go-to-work/next/prev : Step next/prev sub-dir in todo-list.
    next/prev : Must in the dir where has .path_info
    work      : Must in the top dir
EOF
)

_pspl_help=$(cat << EOF
ps1/ps2 , pl1/pl2 :
  Push/Pull file 1/2
    - Must in the dir where has .path_info
    - And .path_info could not be empty

EOF
)

_DEFINE_INFO_PATH_1=.path_info.1
_DEFINE_INFO_PATH_2=.path_info.2
_DEFINE_INFO_PATH=.path_info.in_list

function diff-env-create () {

    local DIR1="$1"
    local DIR2="$2"
    local FILE_LIST="$3"
    local OUTPUT_DIR="$4"

    if [ $# -ne 4 ];then
        echo "$_create_help" ; return
    fi

    if [ ! -d "$1" ]; then
        echo "$_create_help" ; return
    fi
    if [ ! -d "$2" ]; then
        echo "$_create_help" ; return
    fi
    if [ ! -f "$3" ]; then
        echo "$_create_help" ; return
    fi

    local HERE=`pwd`
    local _DIR1=`cd $DIR1 ; pwd`
    local _DIR2=`cd $DIR2 ; pwd`

    mkdir ${OUTPUT_DIR} -p
    local TOP_DIR=`cd ${OUTPUT_DIR}; pwd`
    local TODO_DIR=${TOP_DIR}
    #local TODO_DIR=${TOP_DIR}/todo
    local DONE_DIR=${TOP_DIR}
    #local DONE_DIR=${TOP_DIR}/ok
    mkdir $DONE_DIR -p

    mkdir  ${TODO_DIR} -p
    # 所有待比较的文件都会存在此列表，用于记录工作状态，此表格会随着交互越来越少
    local list_todo=${TODO_DIR}/${_diff_env_list_todo}
    # 所有待比较的文件都会存在此列表，用于恢复初始状态
    local list_todo_ori=${TODO_DIR}/${_diff_env_list_todo_ori}

    touch ${list_todo}
    cp ${FILE_LIST}   ${TODO_DIR}/.list.origin.list

    local i=0
    local ret=0
    for file in `cat $FILE_LIST | sort`
    do
        i=$(($i+1))
        #local SUMMARY=`echo ${file} | md5sum | awk '{print $1}'`
        local FOMAT_NUMBER=`echo $i | awk '{printf("%03d\n",$0)}'`
        local BASE_FILE_NAME=`basename ${file}`
        #local FILE_NAME=${FOMAT_NUMBER}.${SUMMARY}
        local FILE_NAME=${FOMAT_NUMBER}.${BASE_FILE_NAME}
        if [ ! -f "${_DIR1}/${file}" ]; then
            echo ${_DIR1}/${file} >> ${TOP_DIR}/.diff_but_nofound
            echo "? ${file}"
            i=$(($i-1))
            continue
        fi
        if [ ! -f "${_DIR2}/${file}" ]; then
            echo ${_DIR2}/${file} >> ${TOP_DIR}/.diff_but_nofound
            echo "? ${file}"

            i=$(($i-1))
            continue
        fi
        mkdir  ${TODO_DIR}/${FILE_NAME} -p
        diff ${_DIR1}/${file}  ${_DIR2}/${file} > ${TODO_DIR}/${FILE_NAME}/.diff.${BASE_FILE_NAME}
        ret=$?
        if [ $ret -eq 0 ]; then
            rm  ${TODO_DIR}/${FILE_NAME} -rf
            echo ${file} >> ${DONE_DIR}/.diff_but_same
            echo "= ${file}"
            i=$(($i-1))
            continue
        fi

        # 保存信息 以便于 另外的脚本处理
        ## 推拉 有关 操作所需的信息
        ### 路径1
        echo ${_DIR1}/${file} >> ${TODO_DIR}/${FILE_NAME}/${_DEFINE_INFO_PATH_1}
        ### 路径2
        echo ${_DIR2}/${file} >> ${TODO_DIR}/${FILE_NAME}/${_DEFINE_INFO_PATH_2}
        ### 相对路径
        echo ${file}          >> ${TODO_DIR}/${FILE_NAME}/${_DEFINE_INFO_PATH}
        ## 登记当前目录到工作区列表中
        echo ${FILE_NAME} >> ${list_todo}

        # 准备工作区
        ## 拷贝
        cp ${_DIR1}/${file}  ${TODO_DIR}/${FILE_NAME}/1.${BASE_FILE_NAME}
        cp ${_DIR1}/${file}  ${TODO_DIR}/${FILE_NAME}/.bak.1.${BASE_FILE_NAME}
        ## 备份(用于恢复)
        cp ${_DIR2}/${file}  ${TODO_DIR}/${FILE_NAME}/2.${BASE_FILE_NAME}
        cp ${_DIR2}/${file}  ${TODO_DIR}/${FILE_NAME}/.bak.2.${BASE_FILE_NAME}
    done
    local tmp_file_for_sort=`tmp-gen-safe-file`
    cat ${list_todo} | sort > ${tmp_file_for_sort}
    cp ${tmp_file_for_sort} ${list_todo}
    cp ${tmp_file_for_sort} ${list_todo_ori}
    rm ${tmp_file_for_sort}

    echo DIR1 : ${_DIR1} >>  ${TODO_DIR}/.list.origin.paths
    echo DIR2 : ${_DIR2} >>  ${TODO_DIR}/.list.origin.paths

    echo "Creating Backup Repo for This diff-env"
    git-init-repo-with-readme "" "Init" ${TODO_DIR}
    local commit_info=$(cat << EOF
Init diff-env

  Dir 1     : ${_DIR1}
  Dir 2     : ${_DIR2}
  File List : ${FILE_LIST}
EOF
)
    bash <<EOF
    cd ${TODO_DIR}
    git add .
    git commit -m "$commit_info"
EOF
}

function diff-env-cur-item-done() {
    local HERE=`pwd`
    local THIS_DIR=`basename $HERE`

    if [ ! -f ${_DEFINE_INFO_PATH} ]; then
        echo "${_done_skip_help}" ; return
    fi
    if [ ! -f ../.list.todo ]; then
        echo "${_done_skip_help}" ; return
    fi
    cd ..
    file-delete-line-contain-string .list.todo $THIS_DIR
    echo ${THIS_DIR} >> ${_diff_env_list_done}
}

function diff-env-cur-item-skip() {
    local HERE=`pwd`
    local THIS_DIR=`basename $HERE`

    if [ ! -f ${_DEFINE_INFO_PATH} ]; then
        echo "${_done_skip_help}" ; return
    fi
    if [ ! -f ../${_diff_env_list_todo} ]; then
        echo "${_done_skip_help}" ; return
    fi
    cd ..
    file-delete-line-contain-string .list.todo $THIS_DIR
    echo ${THIS_DIR} >> $_diff_env_list_skip
}

function diff-env-cur-item-info() {
    if [ ! -f ${_DEFINE_INFO_PATH_1} ]; then
        echo "Retry if cur dir is in diff-env's item-dir."
        return
    fi

cat <<EOF
[`cat ${_DEFINE_INFO_PATH}`] is from:
 1    :  `cat ${_DEFINE_INFO_PATH_1}`
 2    :  `cat ${_DEFINE_INFO_PATH_2}`

Modify those files by 'vimdiff' or something else,
try 'push/pull' if nedd to modify to theirs home.
use 'cur-item-done/skip' if this item can be DONE.
EOF
}

function diff-env-go-to-work() {
    local HERE=`pwd`
    local THIS_DIR=`basename $HERE`
    local ADir=$1

    if [ ! -f ${_diff_env_list_todo} ]; then
        echo "${_step_help}" ; return
    fi

    # 如果指定了目录
    if [ ! -z "$ADir" ]; then
        cd *${ADir}*
        diff-env-cur-item-info
        return
    fi

    local DIR=`cat .list.todo | head -n 1`
    if [ -z "$DIR" ]; then
        echo "No work to do. ALL OK!   :) "
        return
    fi
    cd $DIR
    diff-env-cur-item-info
}

function diff-env-go-to-next() {
    local HERE=`pwd`
    local THIS_DIR=`basename $HERE`

    if [ ! -f ${_DEFINE_INFO_PATH} ]; then
        diff-env-go-to-work && return 0
        echo "${_step_help}" ; return
    fi
    if [ ! -f ../.list.todo ]; then
        echo "${_step_help}" ; return
    fi
    cd ..
    local break_flag=0
    local NEXT_DIR=""
    for dir in `cat .list.todo`
    do
        if [ $break_flag -ne 0 ]; then
            NEXT_DIR=$dir
            #echo $NEXT_DIR
            break
        fi

        result=`echo $dir | grep $THIS_DIR`
        if [ ! -z "$result" ]; then
            break_flag=1
        fi
    done

    if [ -z "$NEXT_DIR" ]; then
        echo "nowhere to go, try 'go-to-prev'"
        cd ${HERE}
        return
    fi
    cd $NEXT_DIR
    diff-env-cur-item-info
}

function diff-env-go-to-prev() {
    local HERE=`pwd`
    local THIS_DIR=`basename $HERE`

    if [ ! -f ${_DEFINE_INFO_PATH} ]; then
        echo "${_step_help}" ; return
    fi
    if [ ! -f ../.list.todo ]; then
        echo "${_step_help}" ; return
    fi
    cd ..
    local break_flag=0
    local NEXT_DIR=""
    for dir in `cat .list.todo| sort -r`
    do
        if [ $break_flag -ne 0 ]; then
            NEXT_DIR=$dir
            #echo $NEXT_DIR
            break
        fi

        result=`echo $dir | grep $THIS_DIR`
        if [ ! -z "$result" ]; then
            break_flag=1
        fi
    done

    if [  -z "$NEXT_DIR" ]; then
        echo "Maybe nowhere to go?"
        cd ${HERE}
        return
    fi
    cd $NEXT_DIR
    diff-env-cur-item-info
}

## push file 1.* to _DEFINE_INFO_PATH_1
function diff-env-item-1-push-to-ori () {
    if [ ! -f ${_DEFINE_INFO_PATH_1} ]; then
        echo "$_pspl_help" ; return
    fi

    local FILE_OUTPUT=`cat ${_DEFINE_INFO_PATH_1}`
    if [ ! -f ${FILE_OUTPUT} ]; then
        echo "$_pspl_help" ; return
    fi
    # 备份
    echo "Back up"
    cp $FILE_OUTPUT $FILE_OUTPUT.bak -v
    echo "Push file 1"
    cp 1.* $FILE_OUTPUT -v
}

## push file 2.* to _DEFINE_INFO_PATH_2
function diff-env-item-2-push-to-ori () {
    if [ ! -f ${_DEFINE_INFO_PATH_2} ]; then
        echo "$_pspl_help" ; return
    fi

    local FILE_OUTPUT=`cat ${_DEFINE_INFO_PATH_2}`
    if [ ! -f ${FILE_OUTPUT} ]; then
        echo "$_pspl_help" ; return
    fi
    # 备份
    echo "Back up"
    cp $FILE_OUTPUT $FILE_OUTPUT.bak -v
    echo "Push file 2"
    cp 2.* $FILE_OUTPUT -v
}

## Pull file 1.* from _DEFINE_INFO_PATH_1
function diff-env-item-1-pull-from-ori () {
    if [ ! -f ${_DEFINE_INFO_PATH_1} ]; then
        echo "$_pspl_help" ; return
    fi

    local FILE_INPUT=`cat ${_DEFINE_INFO_PATH_1}`
    if [ ! -f ${FILE_INPUT} ]; then
        echo "$_pspl_help" ; return
    fi
    FIL1=`ls 1.* | head -n 1`
    echo "Back up"
    cp $FIL1 .bak.$FIL1 -v
    echo "Pull file 1"
    cp $FILE_INPUT $FIL1 -v
}

## Pull file 2.* from _DEFINE_INFO_PATH_2
function diff-env-item-2-pull-from-ori () {
    if [ ! -f ${_DEFINE_INFO_PATH_2} ]; then
        echo "$_pspl_help" ; return
    fi

    FILE_INPUT=`cat ${_DEFINE_INFO_PATH_2}`
    if [ ! -f ${FILE_INPUT} ]; then
        echo "$_pspl_help" ; return
    fi
    FIL2=`ls 2.* | head -n 1`
    echo "Back up"
    cp $FIL1 .bak.$FIL2 -v
    echo "Pull file 2"
    cp $FILE_INPUT $FIL2 -v
}

function diff-env-help () {
cat <<EOF
1. use 'create' for making a env.
2. use 'go-to-work/next/prev' to item.
3. modify file listed, try 'item-x-push/pull' if you want to modify orignal dir(1 or 2).
3. use 'cur-item-done/skip', retry step [2] until ALL DONE.
EOF
}
